package com.gitee.sparta.core.process.operate;


import java.time.Duration;
import java.util.List;

/**
 * timeout_tab 的操作规范
 * 写：异步
 * 读：同步
 *
 * @param <V>   body 的类型
 * @author zyred
 * @since v 0.0.1
 */
public abstract class AbstractTimeoutTabOperate<V> extends Thread {

    /**
     * 异步写入消息到 timeout_tab 与 metadata_tab 中
     *
     * @param metaId    自定义的消息 id
     * @param topic     topic，用户自定义的
     * @param body      消息体，消息类型泛型
     * @param expire    超时时间单位 ms
     * @param broadcast 是否是广播，广播会进行系列特殊处理 true 是广播 false: 不是广播
     */
    public abstract void writeAsync(String metaId, String topic, V body, long expire, boolean broadcast);

    /**
     * 异步写入消息到 timeout_tab 与 metadata_tab 中
     *
     * @param metaId    自定义的消息 id
     * @param topic     topic，用户自定义的
     * @param body      消息体，消息类型泛型
     * @param times     java.time.Duration 对象
     * @param broadcast 是否是广播，广播会进行系列特殊处理 true 是广播 false: 不是广播
     */
    public abstract void writeAsync(String metaId, String topic, V body, List<Duration> times, boolean broadcast);


    /**
     * 同步写入消息到 timeout_tab 与 metadata_tab 中
     *
     * @param metaId    自定义的消息 id
     * @param topic     topic，用户自定义的
     * @param body      消息体，消息类型泛型
     * @param expire    超时时间 单位 ms
     * @param broadcast 是否是广播，广播会进行系列特殊处理 true 是广播 false: 不是广播
     */
    public abstract  void write(String metaId, String topic, V body, long expire, boolean broadcast);

    /**
     * 同步写入消息到 timeout_tab 与 metadata_tab 中
     *
     * @param metaId    自定义的消息 id
     * @param topic     topic，用户自定义的
     * @param body      消息体，消息类型泛型
     * @param times     java.time.Duration 对象
     * @param broadcast 是否是广播，广播会进行系列特殊处理 true 是广播 false: 不是广播
     */
    public abstract void write(String metaId, String topic, V body, List<Duration> times, boolean broadcast);


    /**
     * 执行搬运操作
     * 该方法是由 sparta 线程执行，不会有任何地方来调用此方法
     * 该方法的逻辑:
     * 1. 根据 0 -> currentTimestamp 的范围进行读取 timeout_tab 中所有的内容
     * 2. 将读取到内容转移到 readable_tab 中，
     * 3. 返回 timeout_tab 中剩下的最小分数
     * 4. 返回所有被执行搬运的 topic
     * 5. 返回所有带有广播的消息
     *
     * @param timeoutTabKey     timeout_tab 的 key 值  {systemName}:timeout_tab
     * @param readableTabKey    readable_tab 的 key 值 {systemName}:readable_tab
     * @param currentTimestamp  系统当前的时间戳，通过 System.currentTimeMillis() 取
     * @param balance           系统隔离
     * @return                  3、4、5 (注释内容)
     */
    public abstract List<Object> carry (String timeoutTabKey, String readableTabKey, long currentTimestamp, String balance);


    /**
     * 拒绝异步队列中添加数据，并且处理完毕队列中的数据
     */
    public abstract void shutdown();

    /**
     * spring boot 正常关机的情况下，钩子函数回调
     * 将 readable_tab 中所有的数据(包含已读和未读)
     * 全部放到 timeout_tab 中，让别人来消费
     */
    public abstract void closeRollback();

}
